package com.groupten.MyController;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.groupten.Entity.ClassPaperEntity;
import com.groupten.Entity.StudentPaperEntity;
import com.groupten.Service.ClassPaperService;
import com.groupten.Service.StudentPaperService;
import com.groupten.Vo.ClassVo;
import com.groupten.Vo.IndividualVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;


@Slf4j
@RestController
@RequestMapping("group/test/")
public class SyxController {

    @Autowired
    private ClassPaperService classPaperService;
    @Autowired
    private StudentPaperService studentPaperService;

    @GetMapping("addStudentPaperToClass")
    public String addStudentPaperToClassPaper() {
        List<StudentPaperEntity> studentPapers = studentPaperService.getUnAddPaper();
        try {
            for (StudentPaperEntity studentPaper : studentPapers) {
                updateClassLevelData(studentPaper);
                studentPaperService.updateIsAddToPaper(studentPaper.getStudentNumber());
            }
        } catch (NullPointerException e) {
            return "There is no studentPaper to add";
        }
        return "success";
    }

    public void updateClassLevelData(StudentPaperEntity studentPaperEntity) {
        ClassPaperEntity classPaperEntity = classPaperService.selectByClassNameAndPaperSession(studentPaperEntity.getClassNumber(),studentPaperEntity.getPaperSession());

        if (classPaperEntity != null) {
            double studentScore = studentPaperEntity.getScore();
            int attendNumber = classPaperEntity.getAttendNumber();
            double averageScore = classPaperEntity.getAverageScore();
            double standardDeviation = classPaperEntity.getStandardDeviation();
            double passingRate = classPaperEntity.getPassingRate();
            double excellentRate = classPaperEntity.getExcellentRate();

            double curAverageScore = updateAverageScore(attendNumber, averageScore, studentScore);
            classPaperEntity.setAverageScore(curAverageScore);
            classPaperEntity.setStandardDeviation(updateStandardDeviation(attendNumber, standardDeviation, studentScore , averageScore ,  curAverageScore));
            classPaperEntity.setPassingRate(updatePassingRate(attendNumber, passingRate, studentScore));
            classPaperEntity.setExcellentRate(updateExcellentRate(attendNumber, excellentRate, studentScore));
            classPaperEntity.setAttendNumber(++attendNumber);

            classPaperService.updateData(classPaperEntity);
        } else {
            classPaperEntity = new ClassPaperEntity();
            classPaperEntity.setAttendNumber(1);
            classPaperEntity.setPaperSession(studentPaperEntity.getPaperSession());
            classPaperEntity.setClassname(studentPaperEntity.getClassNumber());
            classPaperEntity.setAverageScore(updateAverageScore(0, 0, studentPaperEntity.getScore()));
            classPaperEntity.setStandardDeviation(updateStandardDeviation(0 , 0 , studentPaperEntity.getScore() ,
                    0.0 , studentPaperEntity.getScore()));
            classPaperEntity.setPassingRate(updatePassingRate(0, 0, studentPaperEntity.getScore()));
            classPaperEntity.setExcellentRate(updateExcellentRate(0, 0, studentPaperEntity.getScore()));

            classPaperService.insertClassPaper(classPaperEntity);
        }
    }

    public double updateAverageScore(int attendNumber, double averageScore, Double studentScore) {
        averageScore = (averageScore * attendNumber + studentScore) / (attendNumber + 1);
        return averageScore;
    }

    public double updateStandardDeviation(int attendNumber, double standardDeviation, Double studentScore , Double averageScore , Double curAverageScore) {
        double temp = (attendNumber * standardDeviation * standardDeviation ) + ( averageScore * averageScore * attendNumber );
        temp += studentScore * studentScore;
        double result = (temp - (attendNumber + 1) * curAverageScore * curAverageScore) / (attendNumber + 1);
        return Math.sqrt(result);
    }

    public double updatePassingRate(int attendNumber, double passingRate, Double studentScore) {
        if (studentScore < 60) {
            passingRate = (passingRate * attendNumber) / (attendNumber + 1);
            return passingRate;
        } else {
            passingRate = (passingRate * attendNumber + 1) / (attendNumber + 1);
            return passingRate;
        }
    }

    public double updateExcellentRate(int attendNumber, double excellentRate, Double studentScore) {
        if (studentScore < 85) {
            excellentRate = (excellentRate * attendNumber) / (attendNumber + 1);
            return excellentRate;
        } else {
            excellentRate = (excellentRate * attendNumber + 1) / (attendNumber + 1);
            return excellentRate;
        }
    }

    @GetMapping("rankClassPaperBySession")
    public IPage<ClassVo> rankClassPaperBySession(Integer session) {
        IPage<ClassPaperEntity> classPaperEntityIPage = classPaperService.selectByPaperSession(session,1,20);

        try {
            IPage<ClassVo> classVoIPage =  classPaperEntityIPage.convert(classPaperEntity ->{
                ClassVo classVo = new ClassVo();
                BeanUtils.copyProperties(classPaperEntity,classVo);
                return classVo;
            });

            int rank = 1;
            for (ClassVo classVo : classVoIPage.getRecords()) {
                classVo.setClassRank(rank++);
                classPaperService.getMaxAndMinInClass(classVo);
            }

            return classVoIPage;
        } catch (Exception e) {
            return null;
        }
    }

    @GetMapping("selectStudentLevel")
    public IndividualVo selectStudentLevel(String studentNumber, Integer session) {
        StudentPaperEntity studentPaper = studentPaperService.getStudentPaperByStudentNumberAndPaperSession(studentNumber , session);

        IndividualVo individualVo = new IndividualVo();

        if (studentPaper != null) {
            individualVo.setHistoryLowest(100.0);
            individualVo.setHistoryHighest(0.0);
            BeanUtils.copyProperties(studentPaper,individualVo);
            individualVo.setRank(studentPaperService.rankStudentPaper(studentNumber , session , studentPaper.getScore()));
            studentPaperService.FindMaxAndMin(individualVo,session);
        }
        return individualVo;
    }

}
